home *** CD-ROM | disk | FTP | other *** search
- /*
- File: MemoryHandler.c
-
- Contains: xxx put contents here xxx
-
- Version: xxx put version here xxx
-
- Copyright: © 1999 by Apple Computer, Inc., all rights reserved.
-
- File Ownership:
-
- DRI: xxx put dri here xxx
-
- Other Contact: xxx put other contact here xxx
-
- Technology: xxx put technology here xxx
-
- Writers:
-
- (BWS) Brent Schorsch
-
- Change History (most recent first):
-
- <SP1> 7/1/99 BWS first checked in
- */
-
- /*
- These memory routines are kinda handy and solve a lot of problems on the Mac when dealing
- with memory. For instance, people often call DisposeHandle() when they mean to call
- ReleaseResource() and it screws up their resource chain. DisposeHandleZ() checks to see
- if the handle is locked or not, and whether it's a resource or not and takes the appropriate
- action.
-
- All functions ending in 'Z' take the ADDRESS of the Ptr/Handle and set it to nil when it
- disposes of the memory. This is handy because you can then do things like this:
-
- foo = NewPtr();
- DisposePtrZ(&foo);
- ...
- ...
-
- if (foo)
- ...
-
- Probably the most useful of all this stuff are the tagged Ptr and tagged Handle functions.
- Basically what they do is add 12 bytes to the beginning of every block of memory that you
- allocate. The first four bytes are the value kBlockTag. The second is an OSType that
- you provide. The 3rd group of four bytes is a refcon that you provide. This is really
- usefull when working with ZoneRanger or other memory watching tool because when you view
- a block of memory you can see your type and refcon and get a clue as to what the memory
- is. It's really great when you have a memory leak and can't tell what's not getting
- deallocated. Another use is for tracking resources. Pass in the resource type as the
- OSType field and the resource number in the refcon. Then in ZoneRanger you can see
- exactly which resource and number a handle is.
-
- Another use is for reference counting list of similar objects. If you allocate 200 foos
- then set the OSType to 'foo ' and make the refcon the index of which foo it is. This is
- helpful for finding off-by-one loop errors when deallocating lists and arrays.
-
- One other thing that has come in really handy is to set the OSType to some identifier saying
- which source file the block was allocated in and setting the refcon to the line number in
- that source file. That way in ZoneRanger you can tell exactly where that mystery block
- came from.
- */
-
- //• ———————————————————————————————————————— Includes
-
- #include <Dialogs.h>
- #include <Resources.h>
- #include <Windows.h>
-
- #include <string.h>
-
- #include "MemoryHandler.h"
-
- //• ———————————————————————————————————————— Private Definitions
-
- #define kBlockTag "TBLK"
-
- //• ———————————————————————————————————————— Private Types
- //• ———————————————————————————————————————— Private Variables
-
- static UInt32 gAllocatedRam = 0U;
-
- //• ———————————————————————————————————————— Private Functions
- //• ———————————————————————————————————————— Public Variables
-
- //• ———————————————————— IsResourceHandle
-
- Boolean
- IsResourceHandle(Handle theHandle)
- {
- SInt8 memState;
-
- memState = HGetState(theHandle);
-
- //• Check the resource bit in the handle info
- if (memState & 0x20)
- return (true);
-
- return (false);
- }
- //• ———————————————————— IsLockedHandle
-
- Boolean
- IsLockedHandle(Handle theHandle)
- {
- SInt8 memState;
-
- //• Check the lock bit in the handle info
- memState = HGetState(theHandle);
-
- if (memState & 0x80)
- return (true);
-
- return (false);
- }
-
- //• ———————————————————— DisposeControlZ
-
- void
- DisposeControlZ(ControlHandle *theControl)
- {
- if (! (**theControl))
- return;
-
- if (IsLockedHandle((Handle) *theControl))
- HUnlock((Handle) *theControl);
-
- DisposeControl(*theControl);
- *theControl = nil;
- }
-
- //• ———————————————————— DisposeWindowZ
-
- void
- DisposeWindowZ(WindowPtr *theWindow)
- {
- if (nil == theWindow)
- return;
-
- if (nil == *theWindow)
- return;
-
- DisposeWindow(*theWindow);
- *theWindow = nil;
- }
-
- //• ———————————————————— DisposeDialogZ
-
- void
- DisposeDialogZ(DialogPtr *theWindow)
- {
- if (! *theWindow)
- return;
-
- DisposeDialog(*theWindow);
- *theWindow = nil;
- }
-
- //• ———————————————————— DisposeGWorldZ
-
- void
- DisposeGWorldZ(GWorldPtr *theGWorld)
- {
- if (! *theGWorld)
- return;
-
- if (IsLockedHandle((Handle) GetGWorldPixMap(*theGWorld)))
- UnlockPixels(GetGWorldPixMap(*theGWorld));
-
- DisposeGWorld(*theGWorld);
- *theGWorld = nil;
- }
-
- //• ———————————————————— DisposePaletteZ
-
- void
- DisposePaletteZ(PaletteHandle *thePal)
- {
- if (! *thePal)
- return;
-
- if (IsResourceHandle((Handle) *thePal))
- ReleaseResource((Handle) *thePal);
- else
- DisposePalette(*thePal);
-
- *thePal = nil;
- }
-
- //• ———————————————————— KillPictureZ
-
- void
- KillPictureZ(PicHandle *thePicture)
- {
- if (! (**thePicture))
- return;
-
- if (IsLockedHandle((Handle) *thePicture))
- HUnlock((Handle) *thePicture);
-
- if (IsResourceHandle((Handle) *thePicture))
- ReleaseResource((Handle) *thePicture);
- else
- KillPicture(*thePicture);
-
- *thePicture = nil;
- }
-
- //• ———————————————————— DisposePtrZ
-
- void
- DisposePtrZ(Ptr *thePtr)
- {
- if (! *thePtr)
- return;
-
- DisposePtr(*thePtr);
- *thePtr = nil;
- }
-
- //• ———————————————————— DisposeHandleZ
-
- void
- DisposeHandleZ(Handle *theHandle)
- {
- if (! (**theHandle))
- return;
-
- if (IsLockedHandle(*theHandle))
- HUnlock(*theHandle);
-
- if (IsResourceHandle(*theHandle))
- ReleaseResource(*theHandle);
- else
- DisposeHandle(*theHandle);
-
- *theHandle = nil;
- }
-
- //• ———————————————————— TEDisposeZ
-
- void
- TEDisposeZ(TEHandle *theHandle)
- {
- if (! (**theHandle))
- return;
-
- if (IsLockedHandle((Handle) *theHandle))
- HUnlock((Handle) *theHandle);
-
- if (IsResourceHandle((Handle) *theHandle))
- ReleaseResource((Handle) *theHandle);
- else
- TEDispose(*theHandle);
- }
-
- //• ———————————————————— LDisposeZ
-
- void
- LDisposeZ(ListHandle *theHandle)
- {
- if (! (**theHandle))
- return;
-
- if (IsLockedHandle((Handle) *theHandle))
- HUnlock((Handle) *theHandle);
-
- if (IsResourceHandle((Handle) *theHandle))
- ReleaseResource((Handle) *theHandle);
- else
- LDispose(*theHandle);
- }
-
- //• ———————————————————— PurgeAndCompactMem
-
- void
- PurgeAndCompactMem()
- {
- Size growSize;
-
- MaxMem(&growSize);
- }
-
- //• ———————————————————— NewTaggedPtr
-
- Ptr
- NewTaggedPtr(Size size, OSType tag, UInt32 refCon)
- {
- Ptr thePtr;
-
- size += 12;
-
- thePtr = NewPtr(size);
- if (! thePtr)
- return (nil);
-
- BlockMoveData(kBlockTag, thePtr, 4);
- BlockMoveData(&tag, thePtr + 4, 4);
- BlockMoveData(&refCon, thePtr + 8, 4);
-
- gAllocatedRam += size;
-
- return (thePtr + 12);
- }
-
- //• ———————————————————— NewTaggedPtrClear
-
- Ptr
- NewTaggedPtrClear(Size size, OSType tag, UInt32 refCon)
- {
- Ptr thePtr;
-
- size += 12;
-
- thePtr = NewPtrClear(size);
- if (! thePtr)
- return (nil);
-
- BlockMoveData(kBlockTag, thePtr, 4);
- BlockMoveData(&tag, thePtr + 4, 4);
- BlockMoveData(&refCon, thePtr + 8, 4);
-
- gAllocatedRam += size;
-
- return (thePtr + 12);
- }
-
- //• ———————————————————— DisposeTaggedPtr
-
- void
- DisposeTaggedPtr(Ptr thePtr)
- {
- Ptr ptr2;
- Size size;
-
- if (! thePtr)
- return;
-
- ptr2 = thePtr - 12;
- size = GetPtrSize(ptr2);
-
- //• Confirm that this is one of our tagged blocks first
- if (strncmp(kBlockTag, ptr2, 4) == 0)
- {
- DisposePtr(ptr2);
- gAllocatedRam -= size;
- }
- else
- {
- DisposePtr(thePtr);
- }
- }
-
- //• ———————————————————— DisposeTaggedPtrZ
-
- void
- DisposeTaggedPtrZ(Ptr *thePtr)
- {
- Ptr ptr2;
- Size size;
-
- if (! *thePtr)
- return;
-
- ptr2 = (*thePtr) - 12;
- size = GetPtrSize(ptr2);
-
- if (strncmp(kBlockTag, ptr2, 4) == 0)
- {
- DisposePtr(ptr2);
- gAllocatedRam -= size;
- }
- else
- {
- DisposePtr(*thePtr);
- }
-
- *thePtr = nil;
- }
-
- //• ———————————————————— GetAllocatedRam
-
- UInt32
- GetAllocatedRam(void)
- {
- return (gAllocatedRam);
- }